package com.cynteka.cyfoman.core.collection.scxml;

import com.cynteka.cyfoman.core.Util;
import org.apache.commons.chain.Catalog;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ContextBase;
import org.apache.commons.logging.Log;
import org.apache.commons.scxml.ErrorReporter;
import org.apache.commons.scxml.EventDispatcher;
import org.apache.commons.scxml.SCInstance;
import org.apache.commons.scxml.SCXMLExpressionException;
import org.apache.commons.scxml.model.Action;
import org.apache.commons.scxml.model.ModelException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

import java.util.Collection;

/**
 * User: Sergey
 * Date: 10.08.11
 * Time: 13:31
 */
public class ExecuteCommandAction extends Action implements BeanFactoryAware{
    private BeanFactory beanFactory;
    private Catalog catalog;
    private String command;


    @Override
    public void execute(EventDispatcher evtDispatcher, ErrorReporter errRep, SCInstance scInstance, Log appLog, Collection derivedEvents) throws ModelException, SCXMLExpressionException {
        org.apache.commons.scxml.Context scxmlCtx = scInstance.getContext(getParentTransitionTarget());

        initCatalog();

        Command cmd = catalog.getCommand(command);
        ContextBase ctx = new ContextBase();
        ctx.putAll(scxmlCtx.getVars());
        try {
            cmd.execute(ctx);
        } catch (Exception e) {
            // TODO add logging
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    private void initCatalog() {
        catalog = Util.getCatalog(beanFactory);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public String getCommand() {
        return command;
    }

    public void setCommand(String command) {
        this.command = command;
    }
}
